#ifndef __REGISTER_H__
#define __REGISTER_H__

#include <stdlib.h>
#include "tree_dstruct.h"
#include "error.h"
#include "code_gen.h"
#include "list.h"

#define MAX_TABLES 16
#define MAX_ENTRIES 16
#define MAX_REGISTERS 9

typedef enum reg_status {
	LOADED,
	SPILLED,
	NEW
} reg_status_t;

typedef enum reg_type {
	VAR_T,
	TMP_VAR_T,
	TMP_T
} reg_type_t;

typedef struct reg_location {
	reg_status_t status;
	reg_type_t type;
	int offset;
	int k;
	reg_t reg;
} reg_location_t;

typedef struct free_stack_l {
	int offset;
	struct free_stack_l *next;
} free_stack_l_t;

void reg_free(int);
void reg_free_var(int);
void reg_clean_vars();
void reg_load2(int, reg_t, int, reg_t);
int reg_allocate_load1(reg_t, int, reg_t);
int reg_allocate_load2(reg_t, int, reg_t, int, reg_t);
int reg_allocate_load_move2(reg_t, int, reg_t, int, reg_t);
int reg_pre_allocate(int);
int reg_allocate(reg_t);
void reg_var_assign(reg_t, int);
int reg_var_allocate(reg_t, int);
int reg_arg_allocate(reg_t);
int reg_tmp_allocate(reg_t);
int reg_fetch_by_name(char*);
void reg_print_all(void);
void reg_destroy(void);
reg_location_t *reg_get_ptr(int);
char *reg_get_string(reg_t);
reg_t reg_get_name(int);
void reg_load(int, reg_t);
void reg_save_caller_saved(void);
void reg_load_caller_saved(void);

#endif
